package math.vectorSpace.R2;

import math.mathExtended.MathExtended;
import math.vectorSpace.R3.Point3D;
import math.vectorSpace.RX.Vector;

/**
 * Class for creating and working with vectors R2.
 * Contains extensive methods for manipulating vectors.
 * 
 * @author Shimu Wu
 * @version 1.0
 */
public class Vector2D extends Vector<Vector2D> {

    /**
     * Constructs and initialises the zero vector.
     */
    public Vector2D() {
        this(0, 0);
    }

    /**
     * Constructs and initialises a vector with the specified x, y components.
     *
     * @param x the x-component
     * @param y the y-component
     */
    public Vector2D(double x, double y) {
        super(new double[]{x, y});
    }

    /**
     * Constructs and initialises a vector that starts from the origin and extends to the given point.
     *
     * @param point a {@link Point3D} object
     */
    public Vector2D(Point2D point) {
        this(point.getX(), point.getY());
    }

    /**
     * Constructs and initialises a vector that extends from point1 to point2.
     *
     * @param point1 a {@link Point3D} at the tail of the vector
     * @param point2 a {@link Point3D} at the head of the vector
     */
    public Vector2D(Point2D point1, Point2D point2) {
        this(point2.getX() - point1.getX(), point2.getY() - point1.getY());
    }

    /*
    public Vector2D(Vector2D direction, double length) {
    Vector2D temp = direction.unitVector().scale(length);
    this(temp.getX(), temp.getY());
    } */
    /**
     * Returns the x component of this vector.
     *
     * @return the x component of this vector
     */
    public double getX() {
        return super.getComponent(0);
    }

    /**
     * Returns the y component of this vector.
     *
     * @return the y component of this vector
     */
    public double getY() {
        return super.getComponent(1);
    }

    /**
     * Sets the x component of this vector.
     *
     * @param x the x component
     */
    public void setX(double x) {
        super.setComponent(0, x);
    }

    /**
     * Sets the y component of this vector.
     *
     * @param y the y component
     */
    public void setY(double y) {
        super.setComponent(1, y);
    }

    /**
     * Sets the components of this vector to the given x, y components.
     *
     * @param x the x-component
     * @param y the y-component
     */
    public void setVector(double x, double y) {
        setX(x);
        setY(y);
    }

    /**
     * Sets the this vector's components to the given point's coordinates.
     *
     * @param newPoint the {@link Point2D} to set this vector's components to
    
    public void setVector(Point2D newPoint) {
    this.x = newPoint.getX();
    this.y = newPoint.getY();
    }
     */
    /**
     * Sets this vector's components to the given vector's components.
     *
     * @param newVector the Vector2D to set this vector to
     */
    public void setVector(Vector2D newVector) {
        setX(newVector.getX());
        setY(newVector.getY());
    }

    /**
     * Returns the angle in degrees between this vector and the x-axis.
     *
     * @return the angle between this vector and the x-axis in degrees
     */
    public double angleX() {
        return super.angle(0);
    }

    /**
     * Returns the angle in degrees between this vector and the y-axis.
     *
     * @return the angle between this vector and the y-axis in degrees
     */
    public double angleY() {
        return super.angle(1);
    }

    public Vector2D add(double x, double y) {
        return new Vector2D(this.getX() + x, this.getY() + y);
    }

    /**
     * Rotate this Vector2D clockwise
     * @param angle
     * @return 
     */
    public Vector2D rotate(double angle) {
        double x, y, length;
        length = this.length();
        
        // This becomes a really simple rotation in 2D
        x = MathExtended.cosd(angle) * length;
        y = MathExtended.sind(angle) * length;
        
        return new Vector2D(x, y);
    }

    /**
     * Returns the String representation of this vector of the
     * form: Vector2D [x, y].
     *
     * @return the String representation of this vector
     */
    @Override
    public String toString() {
        String temp = "Vector2D [" + Double.toString(this.getX()) + ", "
                + Double.toString(this.getY()) + "]";
        return temp;
    }

    @Override
    protected Vector2D createVector(double[] components) {
        return new Vector2D(components[0], components[1]);
    }
}
